var request = require('request'); /** * ## Responses * Responses from this API with be wrapped in an envelope to assist the caller * in dealing with the various responses from the service. There are no types * to check against in JavaScript, so this facilitates that. * * { * status: 200, * data: { name: "John", age: 29 } * } * * ## Logging * To enable logging, use the NODE_DEBUG environment variable. * * NODE_DEBUG=apidoc * * @constructor */ function Mard2pAPI (host) { var showLogMessages = process.env.NODE_DEBUG ? process.env.NODE_DEBUG.indexOf('apidoc') !== -1 : false; function log (message) { if (showLogMessages) { console.log('[apidoc] ' + message); } } function getQueryString (options) { var params = []; var qs = options.qs || {}; for (var key in qs) { if (qs[key]) { params.push(key + '=' + qs[key]); } } return params.join('&'); } function doRequest (options) { var startMs = Date.now(); options = options || {}; if (!options.json) { options.json = true; } options.qsStringifyOptions = { arrayFormat: 'repeat' }; var queryString = getQueryString(options); var url = options.uri + (queryString ? '?' + queryString : ''); log(options.method + ' ' + url); if (options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH') { log('|--> With body:\n\t\t' + JSON.stringify(options.json)); } return new Promise(function (resolve, reject) { request(options, function (err, response) { if (err) { reject(err); return; } var duration = Date.now() - startMs; var requestHref = response.request ? response.request.href : ''; log('Completed ' + options.method + ' ' + requestHref + ' ' + response.statusCode + ' ' + duration + 'ms'); resolve(response); }); }); } /** * Simple plain object check. This is actually really involved to be 100% * accurate */ function isObject (obj) { return typeof obj === 'object' && !Array.isArray(obj); } var Accounts = (function Accounts() { /** * Used to create an account. * * @param {Object} options * @param {Object} options.data - The request body */ function postCreate(options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/accounts/create'; var queryString = { }; var requestOpts = { qs: queryString, json: options.data, uri: url, method: 'POST' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 409: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Used to update an account. * * @param {string} accountid * @param {Object} options * @param {Object} options.data - The request body */ function putUpdateByAccountid(accountid, options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/accounts/update/' + accountid + ''; var queryString = { }; var requestOpts = { qs: queryString, json: options.data, uri: url, method: 'PUT' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 409: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Delete some account. * * @param {string} accountid */ function deleteDeleteByAccountid(accountid) { var url = host + '/accounts/delete/' + accountid + ''; var queryString = { }; var requestOpts = { qs: queryString, uri: url, method: 'DELETE' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 204: return Promise.resolve(); case 401: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Find account by its id * * @param {string} accountid * @param {Object} options * @param {string} options.ownerid * @param {number} options.totalAmount * @param {number} options.sold * @param {number} options.debit * @param {string} options.currency */ function getByAccountid(accountid, options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/accounts/' + accountid + ''; var queryString = { ownerid: options.ownerid, total_amount: options.totalAmount, sold: options.sold, debit: options.debit, currency: options.currency, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Find all the accounts. * * @param {Object} options * @param {number} options.accountid * @param {string} options.ownerid * @param {number} options.totalAmount * @param {string} options.currency * @param {number} options.sold * @param {number} options.debit */ function getList(options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/accounts/list'; var queryString = { accountid: options.accountid, ownerid: options.ownerid, total_amount: options.totalAmount, currency: options.currency, sold: options.sold, debit: options.debit, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } return { postCreate: postCreate, putUpdateByAccountid: putUpdateByAccountid, deleteDeleteByAccountid: deleteDeleteByAccountid, getByAccountid: getByAccountid, getList: getList, }; }()); var Deposits = (function Deposits() { /** * Delete some deposit. * * @param {string} depid */ function deleteDeleteByDepid(depid) { var url = host + '/deposits/delete/' + depid + ''; var queryString = { }; var requestOpts = { qs: queryString, uri: url, method: 'DELETE' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 204: return Promise.resolve(); case 401: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Find deposit by its id. * * @param {string} depid * @param {Object} options * @param {string} options.paymentMethod * @param {string} options.actorid * @param {number} options.refAccountid * @param {string} options.operatorid * @param {number} options.amount * @param {number} options.phone * @param {number} options.pin * @param {string} options.currency * @param {string} options.paymentContext */ function getByDepid(depid, options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/deposits/' + depid + ''; var queryString = { payment_method: options.paymentMethod, actorid: options.actorid, ref_accountid: options.refAccountid, operatorid: options.operatorid, amount: options.amount, phone: options.phone, pin: options.pin, currency: options.currency, payment_context: options.paymentContext, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * List all the deposits * * @param {Object} options * @param {number} options.payid * @param {string} options.paymentMethod * @param {string} options.actorid * @param {number} options.refAccountid * @param {string} options.operatorid * @param {number} options.amount * @param {number} options.phone * @param {number} options.pin * @param {string} options.currency * @param {string} options.paymentContext */ function getList(options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/deposits/list'; var queryString = { payid: options.payid, payment_method: options.paymentMethod, actorid: options.actorid, ref_accountid: options.refAccountid, operatorid: options.operatorid, amount: options.amount, phone: options.phone, pin: options.pin, currency: options.currency, payment_context: options.paymentContext, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } return { deleteDeleteByDepid: deleteDeleteByDepid, getByDepid: getByDepid, getList: getList, }; }()); var Payments = (function Payments() { /** * Used to create a payment. * * @param {Object} options * @param {Object} options.data - The request body */ function postCreate(options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/payments/create'; var queryString = { }; var requestOpts = { qs: queryString, json: options.data, uri: url, method: 'POST' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 409: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Used to update a payment. * * @param {string} payid * @param {Object} options * @param {Object} options.data - The request body */ function putUpdateByPayid(payid, options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/payments/update/' + payid + ''; var queryString = { }; var requestOpts = { qs: queryString, json: options.data, uri: url, method: 'PUT' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 409: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Delete some payment. * * @param {string} payid */ function deleteDeleteByPayid(payid) { var url = host + '/payments/delete/' + payid + ''; var queryString = { }; var requestOpts = { qs: queryString, uri: url, method: 'DELETE' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 204: return Promise.resolve(); case 401: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Find payment by its id. * * @param {string} payid * @param {Object} options * @param {string} options.paymentMethod * @param {string} options.actorid * @param {number} options.refAccountid * @param {string} options.operatorid * @param {number} options.amount * @param {number} options.phone * @param {number} options.pin * @param {string} options.currency * @param {string} options.paymentContext */ function getByPayid(payid, options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/payments/' + payid + ''; var queryString = { payment_method: options.paymentMethod, actorid: options.actorid, ref_accountid: options.refAccountid, operatorid: options.operatorid, amount: options.amount, phone: options.phone, pin: options.pin, currency: options.currency, payment_context: options.paymentContext, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Find payment by id accountid * * @param {string} refAccountid * @param {Object} options * @param {number} options.payid * @param {string} options.paymentMethod * @param {string} options.actorid * @param {string} options.operatorid * @param {number} options.amount * @param {number} options.phone * @param {number} options.pin * @param {string} options.currency * @param {string} options.paymentContext */ function getByRefAccountid(refAccountid, options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/payments/' + refAccountid + ''; var queryString = { payid: options.payid, payment_method: options.paymentMethod, actorid: options.actorid, operatorid: options.operatorid, amount: options.amount, phone: options.phone, pin: options.pin, currency: options.currency, payment_context: options.paymentContext, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * List all the payments * * @param {Object} options * @param {number} options.payid * @param {string} options.paymentMethod * @param {string} options.actorid * @param {number} options.refAccountid * @param {string} options.operatorid * @param {number} options.amount * @param {number} options.phone * @param {number} options.pin * @param {string} options.currency * @param {string} options.paymentContext */ function getList(options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/payments/list'; var queryString = { payid: options.payid, payment_method: options.paymentMethod, actorid: options.actorid, ref_accountid: options.refAccountid, operatorid: options.operatorid, amount: options.amount, phone: options.phone, pin: options.pin, currency: options.currency, payment_context: options.paymentContext, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } return { postCreate: postCreate, putUpdateByPayid: putUpdateByPayid, deleteDeleteByPayid: deleteDeleteByPayid, getByPayid: getByPayid, getByRefAccountid: getByRefAccountid, getList: getList, }; }()); var Transfers = (function Transfers() { /** * Used to create a transfer resource. * * @param {Object} options * @param {Object} options.data - The request body */ function postCreate(options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/transfers/create'; var queryString = { }; var requestOpts = { qs: queryString, json: options.data, uri: url, method: 'POST' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 409: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Used to update a transfer resource. * * @param {string} transferid * @param {Object} options * @param {Object} options.data - The request body */ function putUpdateByTransferid(transferid, options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/transfers/update/' + transferid + ''; var queryString = { }; var requestOpts = { qs: queryString, json: options.data, uri: url, method: 'PUT' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 409: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Delete some transfer. * * @param {string} transferid */ function deleteDeleteByTransferid(transferid) { var url = host + '/transfers/delete/' + transferid + ''; var queryString = { }; var requestOpts = { qs: queryString, uri: url, method: 'DELETE' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 204: return Promise.resolve(); case 401: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Find transfer by its id * * @param {string} transferid * @param {Object} options * @param {string} options.senderid * @param {number} options.amount * @param {string} options.currency * @param {number} options.refAccountidReceiver * @param {number} options.refAccountidSender */ function getByTransferid(transferid, options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/transfers/' + transferid + ''; var queryString = { senderid: options.senderid, amount: options.amount, currency: options.currency, ref_accountid_receiver: options.refAccountidReceiver, ref_accountid_sender: options.refAccountidSender, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Find all the transfers. * * @param {Object} options * @param {number} options.transferid * @param {string} options.senderid * @param {number} options.amount * @param {string} options.currency * @param {number} options.refAccountidReceiver * @param {number} options.refAccountidSender */ function getList(options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/transfers/list'; var queryString = { transferid: options.transferid, senderid: options.senderid, amount: options.amount, currency: options.currency, ref_accountid_receiver: options.refAccountidReceiver, ref_accountid_sender: options.refAccountidSender, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } return { postCreate: postCreate, putUpdateByTransferid: putUpdateByTransferid, deleteDeleteByTransferid: deleteDeleteByTransferid, getByTransferid: getByTransferid, getList: getList, }; }()); var Validations = (function Validations() { /** * * * @param {Object} options * @param {Object} options.data - The request body */ function post(options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } if (!options.data) { return Promise.reject(new Error('options.data property is required.')); } var url = host + '/validations'; var queryString = { }; var requestOpts = { qs: queryString, json: options.data, uri: url, method: 'POST' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } return { post: post, }; }()); var Withdraws = (function Withdraws() { /** * Delete some withdraw. * * @param {string} wdwid */ function deleteDeleteByWdwid(wdwid) { var url = host + '/withdraws/delete/' + wdwid + ''; var queryString = { }; var requestOpts = { qs: queryString, uri: url, method: 'DELETE' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 204: return Promise.resolve(); case 401: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * Find withdraw by its id. * * @param {string} wdwid * @param {Object} options * @param {number} options.depid * @param {string} options.paymentMethod * @param {string} options.actorid * @param {number} options.refAccountid * @param {string} options.operatorid * @param {number} options.amount * @param {number} options.phone * @param {number} options.pin * @param {string} options.currency * @param {string} options.paymentContext */ function getByWdwid(wdwid, options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/withdraws/' + wdwid + ''; var queryString = { depid: options.depid, payment_method: options.paymentMethod, actorid: options.actorid, ref_accountid: options.refAccountid, operatorid: options.operatorid, amount: options.amount, phone: options.phone, pin: options.pin, currency: options.currency, payment_context: options.paymentContext, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } /** * List all the withdraws * * @param {Object} options * @param {number} options.payid * @param {string} options.paymentMethod * @param {string} options.actorid * @param {number} options.refAccountid * @param {string} options.operatorid * @param {number} options.amount * @param {number} options.phone * @param {number} options.pin * @param {string} options.currency * @param {string} options.paymentContext */ function getList(options) { // if options is not defined, set it options = options || {}; // otherwise if it's not the kind of object we want... if (!isObject(options)) { return Promise.reject(new Error('options parameter is required and must be a plain object')); } var url = host + '/withdraws/list'; var queryString = { payid: options.payid, payment_method: options.paymentMethod, actorid: options.actorid, ref_accountid: options.refAccountid, operatorid: options.operatorid, amount: options.amount, phone: options.phone, pin: options.pin, currency: options.currency, payment_context: options.paymentContext, }; var requestOpts = { qs: queryString, uri: url, method: 'GET' }; return doRequest(requestOpts).then(function (serverResponse) { switch (serverResponse.statusCode) { case 200: return Promise.resolve(serverResponse.body); case 404: return Promise.reject({ status: serverResponse.statusCode, data: serverResponse.body }); default: return Promise.reject(new Error('Unknown response code: ' + serverResponse.statusCode)); } }); } return { deleteDeleteByWdwid: deleteDeleteByWdwid, getByWdwid: getByWdwid, getList: getList, }; }()); this.Accounts = Accounts; this.Deposits = Deposits; this.Payments = Payments; this.Transfers = Transfers; this.Validations = Validations; this.Withdraws = Withdraws; } module.exports = Mard2pAPI;